/*
* File: GroupedTaskIdWidget.java
* Author: Daniel Rogers
* Created on Apr 14, 2008
*
*/
package gri.tasks.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JList;
import gri.tasks.managers.ExtendedTaskDescription;
import gri.tasks.managers.TaskDescription;
import dan.swing.JPrettyLabel;
import dan.swing.PrettyListCellRenderer;
import dan.swing.painters.GradientPainter;
import gri.gui.widgets.options.OptionListWidget;
import gri.gui.widgets.options.Option;
import gri.gui.widgets.WidgetListener;
import gri.gui.widgets.Widget;
import gri.tasks.managers.JobManager;
import java.util.List;
import java.util.ArrayList;
/**
* List widget that displays tasks to select. Each item in the
* list will have a value containing the JobManager and the
* task ID for the listed task.
*
* @author dan.rogers
*/
public class GroupedTaskInfoWidget extends OptionListWidget {
public static final String GROUP_BY_GROUP = "group";
public static final String GROUP_BY_PACKAGE = "package";
String groupBy = GROUP_BY_PACKAGE;
List taskSelectionListeners = new ArrayList();
// ------------------------------------------- Constructors
public GroupedTaskInfoWidget() {
lstValues.setCellRenderer(new CustomListCellRenderer());
addWidgetListener(new InnerListener());
}
// ---------------------------------------- Accessors
public void addTaskSelectionListener(TaskSelectionListener listener) {
taskSelectionListeners.add(listener);
}
// ------------------------------------------- Implementation
/**
* Initialize the list by loading in all tasks from the
* JobManager.
*/
public void addAllTasks(JobManager jobManager) {
String [] taskIds = jobManager.getTaskIds();
for (int i=0; i<taskIds.length; i++)
addTask(jobManager, taskIds[i]);
}
/**
* Adds the given task to the display widget.
*/
public void addTask(JobManager jobManager, String taskId) {
TaskDescription desc = jobManager.getTaskDescription(taskId);
String displayName = desc.getName();
TaskInfo info = new TaskInfo(jobManager, taskId, desc);
addOption(new Option(displayName, info));
}
protected void taskSelected(TaskInfo taskInfo) {
for (int i=0; i<taskSelectionListeners.size(); i++)
((TaskSelectionListener)taskSelectionListeners.get(i)).taskSelected(taskInfo);
}
// ----------------------------------------- Implementation
/**
* Sets a string indicating how tasks are to be grouped.
*/
public void setGroupBy(String groupBy) {
this.groupBy = groupBy;
}
public String getGroupBy() {return groupBy;}
/**
* Adds an option to the list. The value of the option is
* expected to be a string indicating a taskId.
*/
public void addOption(Option option) {
Object value = option.getValue();
if (value instanceof TaskInfo) {
String groupName = getGroup((TaskInfo)value);
GroupElement groupElem = new GroupElement(groupName);
int index = super.lstValuesModel.indexOf(groupElem);
if (index < 0) {
lstValuesModel.addElement(groupElem);
lstValuesModel.addElement(new OptionListItem(option));
}
else {
lstValuesModel.insertElementAt(new OptionListItem(option), index+1);
}
}
else
throw new RuntimeException("This widget only allows TaskEntry values to be given as options");
}
/**
* Determines what group the given task should be in
*/
protected String getGroup(TaskInfo info) {
TaskDescription desc = info.getTaskDescription();
String groupName = null;
if (groupBy.equals(GROUP_BY_GROUP)) {
if (desc instanceof ExtendedTaskDescription)
groupName = ((ExtendedTaskDescription)desc).getGroup();
}
else if (groupBy.equals(GROUP_BY_PACKAGE)) {
if (desc instanceof ExtendedTaskDescription)
groupName = ((ExtendedTaskDescription)desc).getPackageName();
}
if (groupName == null)
groupName = "Other";
return groupName;
}
// ------------------------------------------------------------- Inner Classes
/**
* WidgetListener to convert valueChanged() events to taskSelected()
*/
class InnerListener implements WidgetListener {
public void valueChanged(Widget widget, Object value) {
if (value == null)
taskSelected(null);
if (value instanceof TaskInfo)
taskSelected((TaskInfo)value);
}
}
/**
* Element in the list to present a group name
*/
class GroupElement {
String name;
public GroupElement(String name) {
this.name = name;
}
public String toString() {return name;}
public boolean equals(Object o) {
if (o == null)
return this == null;
if (o instanceof GroupElement)
return ((GroupElement)o).name.equals(this.name);
return false;
}
public int hashCode() {
return name.hashCode();
}
}
class CustomListCellRenderer extends PrettyListCellRenderer {
GradientPainter groupPainter;
GradientPainter selectedPainter;
public CustomListCellRenderer() {
groupPainter = new GradientPainter();
selectedPainter = new GradientPainter();
selectedPainter.setDirection(GradientPainter.TOP_RIGHT_DIAGONAL);
}
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JPrettyLabel label = (JPrettyLabel)super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
//pad five pixels on left and right:
label.setBorder(BorderFactory.createEmptyBorder(0,5,0,5));
label.setOpaque(false);
if (value instanceof GroupElement) {
label.setBorder(BorderFactory.createLineBorder(Color.GRAY));
label.setBackgroundPainter(groupPainter);
label.setFont(label.getFont().deriveFont(Font.BOLD));
}
if (isSelected) {
label.setBackgroundPainter(selectedPainter);
label.setForeground(Color.WHITE);
label.setFont(label.getFont().deriveFont(Font.ITALIC));
}
return label;
}
}
}